package com.swotxu.oldwebproject.redis.listener;

import com.swotxu.oldwebproject.redis.RedisManager;
import javafx.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.exceptions.JedisConnectionException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 注册 redis 监听器
 *
 * @Date: 2020/1/16 15:27
 * @Author: xu.hai
 */
public class JedisPubSubRegistor {
    private static final Logger LOGGER = LoggerFactory.getLogger(JedisPubSubRegistor.class);
    // 事件监听实现类
    private static final List<Pair<JedisPubSub, List<String>>> jedisPubSubList = new ArrayList();
    private static ExecutorService jedisListenerPool;

    static {
        // 注册事件监听 -- redis中 session key过期删除监听
        jedisPubSubList.add(new Pair(
                        new UserRedisSessionListener(), Arrays.asList("__keyevent@%s__:expired", "__keyevent@%s__:del")));
        // 注册事件监听 -- redis中 server idCard key过期监听
        jedisPubSubList.add(new Pair(
                        new ServerOnlineRedisListener(), Arrays.asList("__keyevent@%s__:expired")));
    }
    /**
     * 注册 redis listener
     * @param database
     */
    public static void register(final String database){
        closeRedisListener();
        jedisListenerPool = Executors.newFixedThreadPool(jedisPubSubList.size());

        for (final Pair<JedisPubSub, List<String>> pair : jedisPubSubList) {
            jedisListenerPool.execute(new Runnable() {
                @Override
                public void run() {
                    Jedis jedis = RedisManager.getJedisPool().getResource();
                    if(jedis == null){
                        LOGGER.error("Redis listener registration failed!");
                        return;
                    }
                    // 格式化配置的监听模式
                    List<String> nTopics = format(pair.getValue(), database);
                    LOGGER.info("nTopics: " + nTopics);
                    try {
                        jedis.psubscribe(pair.getKey(), nTopics.toArray(new String[nTopics.size()]));
                    }catch (JedisConnectionException e){
                        LOGGER.info("Redis not available and listener off!");
                    }
                }
            });
        }
    }
    private static List<String> format(List<String> topics, String database){
        List<String> nTopics = new ArrayList<String>();
        for (String topic : topics) {
            nTopics.add(String.format(topic, database));
        }
        return nTopics;
    }

    /**
     * 关闭 redis监听线程池
     */
    public static void closeRedisListener(){
        if(jedisListenerPool != null){
            jedisListenerPool.shutdownNow();
        }
    }
}
